package engine.util.texture;

import java.nio.ByteBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL30;

import static org.lwjgl.opengl.GL11.*;

public class TextureArrayLoader {

	public static int loadTextureArray(String[] files, int minFilter, int magFilter, int textureWrapS, int textureWrapT, boolean mipmapped) {
		String version = GL11.glGetString(GL11.GL_VERSION);
		int v1 = Integer.parseInt(version.charAt(0) + "");
		
		if(v1 < 3) {
			System.err.println("You need opengl version 3.0 or higher to use texture arrays. It could be, that this is not supported on your system. ");
		}
		
		if(files == null || files.length == 0) {
			System.err.println("Invalid nuber of file names while requesting texture array");
			return 0;
		}
		
		RawData[] rawData = new RawData[files.length];
		
		for(int i = 0; i < rawData.length; i++) {
			rawData[i] = TextureLoader.loadRawData(files[i]);
		}
		
		for(int i = 1; i < files.length; i++) {
			if(rawData[0].getWidth() != rawData[i].getWidth() || rawData[0].getHeight() != rawData[i].getWidth()) {
				System.err.println("It is required, that any texture in an array has the same dimension");
				return 0;
			}
			
			if(rawData[0].getSrcPixelFormat() != rawData[i].getSrcPixelFormat() || rawData[0].getDstPixelFormat() != rawData[i].getDstPixelFormat()) {
				System.err.println("It is required, that any texture in an array has the same pixel formats");
			}
		}
		
		ByteBuffer texels = BufferUtils.createByteBuffer(rawData[0].getTextureBuffer().capacity() * rawData.length);
		for(int i = 0; i < rawData.length; i++) {
			rawData[i].getTextureBuffer().rewind();
			texels.put(rawData[i].getTextureBuffer());
		}
		texels.rewind();
		
		int textureID = 0;
		textureID = glGenTextures();
		
		glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, textureID);
		
		glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, textureWrapS);
		glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, textureWrapT);
		glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, minFilter);
		glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, magFilter);
		
		GL12.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, rawData[0].getDstPixelFormat(), rawData[0].getWidth(), rawData[0].getHeight(), rawData.length, 0, rawData[0].getSrcPixelFormat(), GL_UNSIGNED_BYTE, texels);
		
		if(mipmapped) {
			GL30.glGenerateMipmap(GL30.GL_TEXTURE_2D_ARRAY);
		}
		
		glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, 0);
		
		return textureID;
	}
}
